<template>
	<view class="order-warp">
		<view class="address-card">
			<view class="address-top">
				<view class="address-top-title">收货信息</view>
			</view>
			<view class="consignee-info" @click="onOpenPopup('address')">
				<view class="consignee-info-left">
					<view class="member-info">
						{{ currentDeliver.name ? `${currentDeliver.name}${currentDeliver.phone}` : "请选择收货地址" }}
					</view>
					<view class="address">{{ currentDeliver.address }}</view>
				</view>
				<up-icon name="arrow-right" size="14" color="#999999"></up-icon>
			</view>
		</view>

		<view v-for="(order, index) in orderList" :key="index" class="order-card">
			<view class="order-card-top">
				<view class="top-title">
					<up-icon name="bag-fill" size="22" color="#ffffff"></up-icon>
					<view class="title">
						<text>{{ order.supplier }}</text>
						<text style="margin-left: 10rpx">
							（运费：{{ order.express_amount > 0 ? `￥${order.express_amount}` : "包邮" }}）
						</text>
					</view>
				</view>
				<view class="goods-qty">{{ formatGoodsCountText(order.order_lines) }}</view>
			</view>
			<view class="line-list">
				<block v-for="(item, index) in formatOrderLines(order)" :key="index">
					<view class="line-item" v-if="(!order.isMoreGoods && index <= 2) || order.order_lines">
						<up-image width="80" height="80" radius="10" :src="item.image_url" :lazy-load="true"></up-image>
						<view class="line-item-right">
							<view class="goods-name">{{ item.name }}</view>
							<view class="goods-qty">x {{ item.quantity }}</view>
							<u-text
								:text="item.product_attributes.map((i) => `${i.key}:${i.value}`).join(';')"
								color="info"
								size="12"
							></u-text>
							<view class="goods-price">
								<text class="price">
									<text v-if="item.promotional_variant">
										<text>
											￥{{ item.promotional_variant.amount }}
											<text class="unit">/{{ item.product.uom.name }}</text>
										</text>
										<text class="old-price">
											￥{{ item.variant.sale_price }}
											<text class="unit">/{{ item.product.uom.name }}</text>
										</text>
									</text>
									<text v-else>￥{{ item.subtotal_price }}</text>
								</text>
							</view>
						</view>
					</view>
				</block>
			</view>
			<view class="more-btn" v-if="order.order_lines.length > 3" @click="order.isMoreGoods = !order.isMoreGoods">
				<text>{{ order.isMoreGoods ? "查看全部" : "收起" }}</text>
				<view class="more-icon" :class="{ open: !order.isMoreGoods }">
					<up-icon name="arrow-down" size="14" color="#3cb9ef"></up-icon>
				</view>
			</view>
		</view>

		<view class="order-info-card">
			<view class="order-notes">
				<view class="notes-title">订单备注</view>
				<up-textarea
					v-model="params.remark"
					placeholder="留言选填，100字以内"
					count
					maxlength="100"
					height="100"
					:adjustPosition="false"
					@confirm="handleRemarkConfirm"
				></up-textarea>
			</view>
			<view class="order-info-item order-info-border">
				<view class="order-info-key">优惠券</view>
				<view class="select-btn" @click="onOpenPopup('coupon')">
					<view class="select-null" :style="{ color: params.coupon_claim_id ? '#007ecf' : '#999999' }">
						{{ params.coupon_claim_id ? cuurentCoupon.name : "选择优惠券" }}
					</view>
					<up-icon name="arrow-right" size="12" color="#999999"></up-icon>
				</view>
			</view>
			<view class="order-info-item">
				<view class="order-info-key">积分抵扣</view>
				<view class="select-btn">
					<view class="select-null">暂无可使用积分</view>
				</view>
			</view>
		</view>
		<view class="order-info-card">
			<view class="order-info-top">
				<up-icon name="file-text-fill" size="20" color="#000000"></up-icon>
				<view class="title">订单金额</view>
			</view>
			<view class="order-info-item order-info-border">
				<view>标准价格</view>
				<view>￥{{ standPrice }}</view>
			</view>
			<view class="order-info-item order-info-border">
				<view>运费合计</view>
				<view>￥{{ expressAmount }}</view>
			</view>
			<view class="order-info-item">
				<view>合计</view>
				<view>￥{{ totalPrice }}</view>
			</view>
		</view>
		<view class="order-footer">
			<view class="total-money">
				<text class="money-key">实付：</text>
				<text class="money">{{ paymentAmount }}</text>
			</view>
			<up-button
				:customStyle="{
					width: '200rpx',
					backgroundColor: '#66E87B',
					color: '#ffffff',
					borderColor: '#66E87B',
					margin: 0
				}"
				text="确认订单"
				:loading="submitLoading"
				@click="handleSubmit"
			></up-button>
		</view>

		<!-- 弹出框 -->
		<up-popup :show="popupShow" round="10">
			<!-- 弹出框主体 -->
			<view class="popup-main">
				<!-- 弹出框顶部 -->
				<view class="popup-top">
					<!-- 空白按钮 -->
					<view class="popup-btn"></view>
					<!-- 弹出框标题 -->
					<view class="popup-title">{{ popupType == "address" ? "我的收货地址" : "优惠券" }}</view>
					<!-- 关闭按钮 -->
					<view class="popup-btn" @click="onClosePopup">
						<!-- 关闭图标 -->
						<up-icon name="close" size="18" color="#666666"></up-icon>
					</view>
				</view>
				<!-- 弹出框内容 -->
				<view class="popup-content">
					<scroll-view scroll-y style="height: 100%;">
					<!-- 地址选择弹出框内容 -->
					<view class="popup-address" v-if="popupType == 'address'">
						<!-- 地址列表 -->
						<view class="address-list">
							<!-- 循环渲染地址列表 -->
							<view
								:class="['address-item', currentDeliver.id == deliver.id ? 'active' : '']"
								v-for="(deliver, index) in store.state.deliver.list"
								:key="index"
								@click="handleSelectDeliver(deliver)"
							>
								<!-- 地址城市信息 -->
								<view class="address-city">
									<!-- 城市名称 -->
									<view class="city-name">
										{{ `${deliver.province.name} ${deliver.city.name} ${deliver.district.name}` }}
									</view>
									<!-- 城市标签 -->
									<view class="city-tag">门店地址</view>
								</view>
								<!-- 地址详情 -->
								<view class="address-info">{{ deliver.address }}</view>
								<!-- 会员信息 -->
								<view class="member-info">
									<!-- 收货人姓名 -->
									<view class="name">{{ deliver.name }}</view>
									<!-- 收货人电话 -->
									<view class="phone">{{ deliver.phone }}</view>
									<!-- 默认地址标签 -->
									<view class="tag" v-if="deliver.is_default">默认</view>
								</view>
							</view>
						</view>
					</view>
					<!-- 优惠券选择弹出框内容 -->
					<view class="popup-coupon" v-if="popupType == 'coupon'">
						<!-- 垂直滚动视图 -->
						<scroll-view scroll-y style="height: 600rpx">
							<!-- 有可用优惠券时渲染 -->
							<template v-if="canUseCouponList.length">
								<!-- 优惠券列表容器 -->
								<view class="p-20" style="overflow: hidden">
									<!-- 循环渲染优惠券 -->
									<my-coupon
										v-for="item in canUseCouponList"
										:key="item.id"
										:data="item.coupon"
										:isActive="item.id == params.coupon_claim_id"
										@click="handleSwitchCoupon(item)"
									></my-coupon>
								</view>
							</template>
							<!-- 无可用优惠券时显示空状态 -->
							<my-empty v-else type="coupon" text="暂无可用优惠券" marginTop="">
								<!-- 去看看按钮 -->
								<view class="mt-20">
									<up-button type="primary" @click="handleToCoupon">去看看</up-button>
								</view>
							</my-empty>
						</scroll-view>
					</view>
					</scroll-view>
				</view>
			</view>
		</up-popup>
	</view>
</template>

<script setup>
import { onReady } from "@dcloudio/uni-app";
import { computed, reactive, ref, watch } from "vue";
import { useStore } from "vuex";
import { wechatPayInfo, cancelWechatPayOrder } from "@/common/apis/order";
import { supplierDetail } from "@/common/apis/supplier.js";

// 获取 vuex store 实例
const store = useStore();

// 弹出框显示状态
const popupShow = ref(false);

// 弹出框类型，可选值为 'address' 或 'coupon'
const popupType = ref("address");

// 订单参数
const params = reactive({
	lines: [],
	deliver_id: "",
	remark: "",
	coupon_claim_id: null
});

const beforeData = ref({
	express_cost_data: [], //快递成本数据
	express_amount: 0, //快递金额
	is_multi_order: false, //是否为多订单
	is_sub_order: false, //是否为子订单
	code: "", //订单编号
	user_id: 0, //用户 ID
	merchant_id: 0, //商户 ID
	supplier_id: null, //供应商 ID
	type: "merchant", //类型，【merchant】商户订单
	remark: "", //备注
	deliver: {
		name: "", //收件人姓名
		phone: "", //收件人电话
		address: "", //收件人地址
		province_id: 0, //省份 ID
		city_id: 0, //城市 ID
		district_id: 0 //区县 ID
	}, //配送信息
	status: "pending", //状态，【pending】待支付
	payment_amount: 0, //实际需要支付金额
	total_price: 0, //总价格
	total_stand_price: 0, //总标准价格
	sub_orders: [], //子订单
	order_lines: [] //订单行
});

// 当前选中的优惠券
const cuurentCoupon = ref({});

// 可使用的优惠券列表，通过计算属性从 store 中筛选
const canUseCouponList = computed(() => {
	return store.state.coupon.list.filter((i) => {
		return Number(totalPrice.value) > Number(i.coupon.value);
	});
});

// 商品列表，从 store 中获取
const orderList = computed(() => {
	return beforeData.value.sub_orders;
});

// 当前选中的收货地址
const currentDeliver = ref({
	id: "",
	name: "",
	phone: "",
	address: ""
});

// 格式化商品数量文本，显示商品种类和总件数
const formatGoodsCountText = computed(() => {
	return (lines) => {
		const cateCount = lines.length;
		let totalCount = 0;
		lines.forEach((i) => {
			totalCount += i.quantity;
		});
		return `${cateCount}种${totalCount}件`;
	};
});

// 商品合计金额，通过计算属性计算
const standPrice = computed(() => {
	return Number(beforeData.value.total_stand_price).toFixed(2);
});

// 订单合计金额，目前等于商品合计金额
const totalPrice = computed(() => {
	return Number(beforeData.value.payment_amount).toFixed(2);
});

// 实际支付金额
const paymentAmount = computed(() => {
	return Number(beforeData.value.payment_amount).toFixed(2);
});

// 运费
const expressAmount = computed(() => {
	return Number(beforeData.value.express_amount).toFixed(2);
});

watch([() => params.deliver_id, () => params.coupon_claim_id], async () => {
	await handleBeforeOrderCreate();
});

function formatOrderLines(order) {
	console.log(order);
	if (order.isMoreGoods) {
		return order.order_lines.slice(0, 3);
	}
	return order.order_lines;
}

async function generateOrderLines(order) {
	const supplier = await supplierDetail(order.supplier_id);
	if (supplier) {
		order.supplier = supplier.name;
	}
	order.isMoreGoods = order.order_lines.length > 3;
	order.order_lines.forEach((i) => {
		const selectGoodsList = store.state.order.selectGoodsList;
		const index = selectGoodsList.findIndex((item) => item.product.id === i.product_id);
		if (index !== -1) {
			i.image_url = selectGoodsList[index].variant.image_url
				? selectGoodsList[index].variant.image_url
				: selectGoodsList[index].product.image_url;
		}
	});
}

async function handleBeforeOrderCreate() {
	submitLoading.value = true;
	try {
		submitLoading.value = true;
		const response = await store.dispatch("fetchBeforeOrderCreate", params);
		if (response) {
			// 单订单的话处理一下数据类型与多订单保持一致
			if (!response.is_multi_order) {
				response.sub_orders = [JSON.parse(JSON.stringify(response))];
			}
			const promises = [];
			// 遍历子订单，创建获取供应商详情的 Promise 数组
			response.sub_orders.forEach((i) => {
				promises.push(generateOrderLines(i));
			});
			await Promise.all(promises);
			beforeData.value = response;
		}
		submitLoading.value = false;
	} catch (err) {
		submitLoading.value = false;
	}
}

function isMoreGoods(length) {
	return length > 3;
}

/**
 * 关闭弹出框
 */
function onClosePopup() {
	popupShow.value = false;
	popupType.value = "";
}

/**
 * 打开弹出框
 * @param {string} type - 弹出框类型，可选值为 'address' 或 'coupon'
 */
function onOpenPopup(type) {
	popupShow.value = true;
	popupType.value = type;
}

/**
 * 处理选择收货地址
 * @param {Object} e - 选中的收货地址对象
 */
function handleSelectDeliver(e) {
	currentDeliver.value = e;
	popupShow.value = false;
	params.deliver_id = currentDeliver.value.id;
}

// 提交按钮加载状态
const submitLoading = ref(false);

/**
 * 微信小程序支付
 * @param {string} out_trade_no - 订单号
 * @param {string} orderId - 订单id
 * @returns {Promise} - 支付结果的 Promise
 */
function fetchWechatPay(out_trade_no, orderId) {
	return new Promise((resolve, reject) => {
		// 调用 uni.login 获取登录凭证
		uni.login({
			success: async (res) => {
				try {
					// 调用接口获取支付信息
					const { data: payInfo } = await wechatPayInfo({
						out_trade_no,
						code: res.code
					});
					if (payInfo) {
						// 调用微信支付接口
						uni.requestPayment({
							provider: "wxpay",
							package: payInfo.package,
							nonceStr: payInfo.nonceStr,
							signType: payInfo.signType,
							timeStamp: payInfo.timeStamp,
							paySign: payInfo.paySign,
							orderInfo: payInfo,
							success: resolve,
							fail: async (err) => {
								// 支付失败，取消微信支付订单
								await cancelWechatPayOrder({ out_trade_no });
								uni.$u.toast("支付失败");
								// 跳转到订单列表页
								uni.redirectTo({
									url: `/pages/order/detail?id=${orderId}`
								});
								reject(err);
							}
						});
					} else {
						reject();
					}
				} catch (err) {
					reject(err);
				}
			}
		});
	});
}

/**
 * @description Batch delete cart
 * @returns Promise
 */
async function fetchBatchDeleteCart() {
	const promises = [];
	// 遍历选中的商品列表，创建删除购物车项的 Promise 数组
	store.state.order.selectGoodsList.forEach((i) => {
		promises.push(store.dispatch("fetchDelCart", i.id));
	});
	// 并行执行所有删除操作
	return await Promise.all(promises);
}

/**
 * 处理提交订单
 */
async function handleSubmit() {
	if (!params.deliver_id) {
		uni.$u.toast("请选择收货地址");
		return;
	}
	// 设置提交按钮为加载状态
	submitLoading.value = true;
	// 显示加载提示
	uni.showLoading();
	try {
		// 调用 store 中的 action 创建订单
		const response = await store.dispatch("fetchAddOrder", params);
		// 批量删除购物车中的商品
		await fetchBatchDeleteCart();
		if (response) {
			// 调用 store 中的 action 创建支付订单
			const result = await store.dispatch("fetchAddPayOrder", response.id);
			if (result.data) {
				// 显示等待支付提示
				uni.showLoading({ title: "等待支付...", mask: true });
				// 调用微信支付函数
				await fetchWechatPay(result.data.out_trade_no, response.id);
				// 隐藏加载提示
				uni.hideLoading();

				// 轮询获取支付结果
				const pollInterval = 1000; // 轮询间隔，单位：毫秒
				const maxPollCount = 30; // 最大轮询次数
				let pollCount = 0;

				/**
				 * 检查支付状态
				 */
				const checkPaymentStatus = async () => {
					try {
						// 调用 store 中的 action 获取支付状态
						const paymentStatus = await store.dispatch("fetchPaymentStatus", {
							out_trade_no: result.data.out_trade_no
						});
						if (paymentStatus === "paid") {
							uni.hideLoading();
							uni.showModal({
								title: "提示",
								content: "支付成功",
								confirmText: "查看订单",
								showCancel: false,
								success: (r) => {
									if (r.confirm) {
										// 支付成功，跳转到订单详情页
										uni.redirectTo({
											url: `/pages/order/detail?id=${response.id}`
										});
									}
								}
							});

							return;
						}
						if (pollCount < maxPollCount) {
							// 未达到最大轮询次数，继续轮询
							pollCount++;
							setTimeout(checkPaymentStatus, pollInterval);
						} else {
							// 达到最大轮询次数，提示查询超时
							uni.$u.toast("支付结果查询超时，请稍后查看订单状态");
						}
					} catch (error) {
						console.error("查询支付状态出错:", error);
						uni.hideLoading();
						if (pollCount < maxPollCount) {
							// 出现错误，未达到最大轮询次数，继续轮询
							pollCount++;
							setTimeout(checkPaymentStatus, pollInterval);
						} else {
							// 达到最大轮询次数，提示查询超时
							uni.$u.toast("支付结果查询超时，请稍后查看订单状态");
						}
					}
				};

				uni.showLoading({ title: "查询支付结果,请勿退出", mask: true });

				// 开始检查支付状态
				await checkPaymentStatus();
			}
		}
		// 提交完成，取消加载状态
		submitLoading.value = false;
		// 隐藏加载提示
		uni.hideLoading();
	} catch (err) {
		// 出现错误，取消加载状态
		submitLoading.value = false;
		// 隐藏加载提示
		uni.hideLoading();
	}
}

/**
 * 处理切换优惠券
 * @param {Object} e - 选中的优惠券对象
 */
function handleSwitchCoupon(e) {
	if (params.coupon_claim_id == e.id) {
		// 取消选中当前优惠券
		params.coupon_claim_id = undefined;
		cuurentCoupon.value = {};
	} else {
		// 选中新的优惠券
		params.coupon_claim_id = e.id;
		cuurentCoupon.value = e.coupon;
	}
	// 关闭弹出框
	popupShow.value = false;
}

/**
 * 跳转到优惠券页面
 */
function handleToCoupon() {
	// 跳转到优惠券页面
	uni.navigateTo({
		url: "/pages/user/coupon"
	});
}

/**
 * @description 备注确认
*/
function handleRemarkConfirm() {
	uni.hideKeyboard();
}

/**
 * 页面初次渲染完成时的钩子函数
 */
onReady(async () => {
	// 初始化订单参数中的商品行信息
	store.state.order.selectGoodsList.forEach((i, index) => {
		params.lines.push({
			product_id: i.product.id,
			quantity: i.quantity,
			variant_id: i.variant.id
		});
	});
	// 调用 store 中的 action 获取收货地址列表
	await store.dispatch("fetchDeliverList");
	if (store.getters.defaultDeliver) {
		// 如果有默认收货地址，设置为当前选中的收货地址
		currentDeliver.value = store.getters.defaultDeliver;
		params.deliver_id = currentDeliver.value.id;
	} else if (store.state.deliver.list.length) {
		currentDeliver.value = store.state.deliver.list[0];
		params.deliver_id = currentDeliver.value.id;
	}
});
</script>

<style scoped lang="scss">
.order-warp {
	padding: 20rpx 20rpx 180rpx;

	.address-card {
		padding: 20rpx;
		border-radius: 20rpx;
		margin-bottom: 20rpx;
		background-color: #ffffff;

		.address-top {
			display: flex;
			align-items: center;
			margin-bottom: 20rpx;

			.address-top-title {
				font-weight: bold;
				font-size: 30rpx;
				margin-left: 10rpx;
			}
		}

		.consignee-info {
			display: flex;
			align-items: center;
			justify-content: space-between;

			.consignee-info-left {
				flex: 1;
				margin-right: 20rpx;

				.address {
					flex: 1;
					color: #999999;
					margin-right: 20rpx;
				}
			}
		}
	}

	.order-card {
		border-radius: 20rpx;
		overflow: hidden;
		background-color: #ffffff;
		margin-bottom: 20rpx;

		.order-card-top {
			padding: 20rpx;
			// background-color: #44bdf1;
			background-color: #66e87b;
			display: flex;
			align-items: center;
			justify-content: space-between;

			.top-title {
				display: flex;
				align-items: center;

				.title {
					font-size: 30rpx;
					font-weight: bold;
					margin-left: 6rpx;
					color: #ffffff;
				}
			}

			.goods-qty {
				font-size: 28rpx;
				font-weight: bold;
				color: #ffffff;
			}
		}

		.line-list {
			padding: 0 20rpx;

			.line-item {
				padding: 20rpx 0;
				border-bottom: 2rpx solid #f0f0f0;
				display: flex;
				justify-content: space-between;

				.line-item-right {
					margin-left: 20rpx;
					display: flex;
					flex-direction: column;
					justify-content: space-between;
					flex: 1;
					padding: 10rpx 0;

					.goods-name {
						font-size: 30rpx;
						font-weight: bold;
						margin-bottom: 10rpx;
					}

					.price {
						font-size: 32rpx;
						font-weight: bold;
						color: #ff0000;

						.old-price {
							color: #ccc;
							text-decoration: line-through;
							margin-left: 5px;
						}
					}

					.goods-qty {
						font-size: 24rpx;
						color: #999999;
					}
				}
			}

			& .line-item:last-child {
				border-bottom: 0;
			}
		}

		.more-btn {
			color: #3cb9ef;
			display: flex;
			align-items: center;
			justify-content: center;
			padding: 20rpx 0;

			.more-icon {
				margin-left: 10rpx;
				transition: all ease 0.5s;

				&.open {
					transform: rotateZ(-180deg);
				}
			}
		}
	}

	.order-info-card {
		border-radius: 20rpx;
		margin-bottom: 20rpx;
		background-color: #ffffff;

		.order-notes {
			border-top: 2rpx solid #f0f0f0;
			padding: 20rpx;

			.notes-title {
				font-size: 30rpx;
				font-weight: bold;
				margin-bottom: 20rpx;
			}
		}

		.order-info-top {
			display: flex;
			align-items: center;
			padding: 20rpx 20rpx 0;

			.title {
				font-size: 30rpx;
				font-weight: bold;
			}
		}

		.order-info-border {
			border-bottom: 2rpx solid #f0f0f0;
		}

		.order-info-item {
			margin: 0 20rpx;
			height: 100rpx;
			display: flex;
			align-items: center;
			justify-content: space-between;

			.order-info-key {
				font-weight: bold;
			}

			.select-btn {
				display: flex;
				align-items: center;

				.select-null {
					color: #999999;
				}
			}
		}
	}

	.order-footer {
		padding: 20rpx 20rpx calc(env(safe-area-inset-bottom) + 20rpx);
		background-color: #ffffff;
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		border-top: 2rpx solid #f0f0f0;
		display: flex;
		align-items: center;
		justify-content: space-between;

		.total-money {
			display: flex;
			align-items: flex-end;

			.money-key {
				font-size: 24rpx;
			}

			.money {
				font-size: 38rpx;
				font-weight: bold;
				color: #ff0000;

				&::before {
					content: "￥";
					font-weight: bold;
					color: #ff0000;
					font-size: 24rpx;
				}
			}
		}
	}

	.popup-main {
		.popup-top {
			display: flex;
			align-items: center;
			justify-content: space-between;
			padding: 20rpx;

			.popup-btn {
				width: 50rpx;
			}

			.popup-title {
				font-size: 32rpx;
				font-weight: bold;
			}
		}

		.popup-content {
			height: 600rpx;

			.popup-address {
				.address-list {
					.address-item {
						padding: 20rpx;
						border-bottom: 2rpx solid #f0f0f0;

						.address-city {
							display: flex;
							align-items: center;
							justify-content: space-between;
							margin-bottom: 10rpx;

							.city-name {
								font-size: 26rpx;
							}

							.city-tag {
								border-radius: 4rpx;
								padding: 6rpx 10rpx;
								background-color: #66e87b;
								font-size: 24rpx;
								color: #ffffff;
							}
						}

						.address-info {
							font-size: 32rpx;
							margin-bottom: 10rpx;
						}

						.member-info {
							display: flex;
							align-items: center;

							.tag {
								padding: 4rpx 8rpx;
								border-radius: 4rpx;
								background-color: #66e87b;
								font-size: 24rpx;
								color: #ffffff;
								margin-left: 20rpx;
							}
						}

						&.active {
							.city-name {
								color: $u-primary;
							}
							.address-info {
								color: $u-primary;
							}
							.member-info {
								color: $u-primary;
							}
						}
					}
				}
			}
		}
	}
}
</style>
